﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Modules.VocabularyTrainer.Shared.Locator;
using Genius.Brain.Shared;
using Genius.Brain.Shared.BO;
using Genius.Brain.Shared.Locator;
using Modules.VocabularyTrainer.Shared.Strategy;
using Genius.Brain.Shared.Strategy;

namespace Modules.VocabularyTrainer.Impl
{
    class GeniusModule : IGeniusModule
    {
        private static readonly string K_Question = "Question";
        private static readonly string K_Mode = "Mode";
        private static readonly string K_Language = "Language";
        private static readonly string K_Native = "Native";

        private static Random rnd = new Random();

        private Dictionary<VocabularyMatchRate, string> _rateToken;
        private Dictionary<string, IVocabularyMatchRateStrategy> _textMatcherRateStrategy;
        private Dictionary<string, ITranslatorStrategy> _translatorStrategy;
        private ITextParserStrategy _textParserStrategy;
        private ITextFormaterStrategy _textFormaterStrategy;

        public GeniusModule()
        {
            //Configure 
            _rateToken = new Dictionary<VocabularyMatchRate, string>();
            _rateToken[VocabularyMatchRate.None] = "#ISRIGHT";
            _rateToken[VocabularyMatchRate.WrongCase] = "#ISWRONGCASEXISRIGHT";
            _rateToken[VocabularyMatchRate.WrongDiacritics] = "#ISWRONGDIACRITICSXISRIGHT";
            _rateToken[VocabularyMatchRate.MissingMark] = "#ISWRONGPUNCTATIONXISRIGHT";
            _rateToken[VocabularyMatchRate.WrongMark] = "#ISWRONGPUNCTATIONXISRIGHT";


            _rateToken[VocabularyMatchRate.WrongArticle] = "#ISWRONGARTICLEXISRIGHT";
            _rateToken[VocabularyMatchRate.MissingArticle] = "#ISWRONGARTICLEXISRIGHT";
            _rateToken[VocabularyMatchRate.WrongPreposition] = "#ISWRONGPREPOSITIONXISRIGHT";
            _rateToken[VocabularyMatchRate.MissingPreposition] = "#ISWRONGPREPOSITIONXISRIGHT";

            _translatorStrategy = new Dictionary<string, ITranslatorStrategy>();
            _translatorStrategy["es"] = VocabularyTrainerLocator.GetTranslatorStrategy(@"Data\dictionary_de_es.json");
            _translatorStrategy["en"] = VocabularyTrainerLocator.GetTranslatorStrategy(@"Data\dictionary_de_en.json");
            _translatorStrategy["de"] = VocabularyTrainerLocator.GetTranslatorStrategy(@"Data\dictionary_de_en.json");

            _textMatcherRateStrategy = new Dictionary<string, IVocabularyMatchRateStrategy>();
            _textMatcherRateStrategy["es"] = VocabularyTrainerLocator.VocabularyMatchRateStrategy(@"Data\configuration_es.json");
            _textMatcherRateStrategy["de"] = VocabularyTrainerLocator.VocabularyMatchRateStrategy(@"Data\configuration_de.json");
            _textMatcherRateStrategy["en"] = VocabularyTrainerLocator.VocabularyMatchRateStrategy(@"Data\configuration_en.json");

            var files = new string[]{ @"Data\vocabulary_es.json" , @"Data\vocabulary_en.json"  , @"Data\vocabulary_de.json" };
            _textParserStrategy = BrainLocator.GetTextParserStrategy(files);  
            _textFormaterStrategy = BrainLocator.GetTextFormaterStrategy(files); 
        }


        public GeniusModuleState RecvMessage(IDialogContext context, IMessage message, IMessage response)
        {

            //https://de.wikibooks.org/wiki/Spanisch-Kurs:_Lektion_3
        

            if (!context.Has(K_Mode))
                    return IsHello(context,message,response);

            if (context.Value<string>(K_Mode).Equals("INIT"))
            {
                if (context.Has(K_Question))
                {
                    return Init(context, message, response);
                }
            }
            if (context.Value<string>(K_Mode).Equals("ASK"))
                return Ask(context, message, response);

            //Error: unknown Mode or no Question
            return GeniusModuleState.None;
        }

        private GeniusModuleState AskVocabulary(IDialogContext context, IMessage message, IMessage response)
        {
            var language = context.Value<string>(K_Language);
            var native = context.Value<string>(K_Native);

            context.Set(K_Question, BrainLocator.GetText("#HOWDOYOUSAY", language));
            var words = _translatorStrategy[language].GetWords(native, 0, 30);
            var count = words.Count();
            int ix = rnd.Next(count);

            context.Value<IText>(K_Question).Params["word"] = words[ix];
            if (!String.IsNullOrWhiteSpace(response.Text))
                response.Text += " ";
            response.Text += _textFormaterStrategy.Format(context.Value<IText>(K_Question));

            return GeniusModuleState.Cont;
        }


        private GeniusModuleState Ask(IDialogContext context, IMessage message, IMessage response)
        {
            var Text = _textParserStrategy.Parse(message.Text);
            var language = context.Value<string>(K_Language);
            var native = context.Value<string>(K_Native);

            //Auswerten der Antworten
            if (context.Has(K_Question))
            {
                if (context.Value<IText>(K_Question).Token.Equals("#HOWDOYOUSAY"))
                {
                    //Wie sagt man auf Spanisch => dialog.Question.Params["word"]
                    var translatedWord = _translatorStrategy[language].GetTranslation(native, language, context.Value<IText>(K_Question).Params["word"]);


                    if (Text.Token.Equals("#DONOTKNOW"))
                    {
                        var partext = BrainLocator.GetText("#NOPROBLEMXISRIGHT", language);
                        partext.Params["word"] = translatedWord;
                        response.Text = _textFormaterStrategy.Format(partext);
                    }
                    else
                    {
                        var textMatcherStrategy = BrainLocator.GetTextMatcherStrategy();
                        var match = textMatcherStrategy.Match(translatedWord, message.Text);

                        var token = "#ISWRONGXISRIGHT";   //Default
                        var rate = _textMatcherRateStrategy[language].Rate(match);
                        if (_rateToken.ContainsKey(rate))
                            token = _rateToken[rate];

                        var partext = BrainLocator.GetText(token, language);
                        partext.Params["word"] = translatedWord;
                        response.Text = _textFormaterStrategy.Format(partext);
                    }
                }
                //else Andere Frage???
                context.Remove(K_Question);
            }
            return AskVocabulary(context, message, response);
        }

        private GeniusModuleState Init(IDialogContext context, IMessage message, IMessage response)
        {
            var Text = _textParserStrategy.Parse(message.Text);
            var language = context.Value<string>(K_Language);

            if (context.Value<IText>(K_Question).Token.Equals("#WANTLEARNLANGUAGE") ||
                context.Value<IText>(K_Question).Token.Equals("#DONTUNDERSTAND"))
            {

                if (Text.Token.Equals("#YES"))
                {
                    //Aprende Espanol - Modus 
                    context.Set(K_Mode, "ASK");
                    context.Remove(K_Question);

                    return AskVocabulary(context, message, response);
                }
                if (Text.Token.Equals("#NO"))
                {
                    context.Remove(K_Question);
                    response.Text = _textFormaterStrategy.Format(BrainLocator.GetText("#HOWSAD", language));
                    return GeniusModuleState.Once; //Module Ende
                }
            }

            context.Set(K_Question, BrainLocator.GetText("#DONTUNDERSTAND", language));
            response.Text = _textFormaterStrategy.Format(context.Value<IText>(K_Question));
            return GeniusModuleState.Cont;
        }

       

        private GeniusModuleState IsHello(IDialogContext context, IMessage message, IMessage response)
        {
            var Text = _textParserStrategy.Parse(message.Text);

            if (Text.Token.Equals("#HELLO"))
            {
                var language = Text.Language;
                var native = "de";
                if (language.Equals("de"))
                {
                    native = "en";
                }
                context.Set(K_Language, language);
                context.Set(K_Native, native);
                context.Set(K_Mode, "INIT");
                context.Set(K_Question, BrainLocator.GetText("#WANTLEARNLANGUAGE", language));
                response.Text = _textFormaterStrategy.Format(context.Value<IText>(K_Question));
                return GeniusModuleState.Cont;
            }
            return GeniusModuleState.None;
        }
    }
}
